package handler

import (
	"github.com/gin-gonic/gin"
	"hcy-api/lib/http"
	"hcy-api/lib/id"
	"hcy-api/structs/enum"
	"hcy-api/structs/lms"
	"hcy-api/structs/tables"
	"lms/global"
	"lms/repository"
	"time"
)

var QuestionApi = new(questionApi)

type questionApi struct {
}

func (a questionApi) QuestionFolderList(c *gin.Context) {
	li, err := repository.ExamDB.FindQuestionFolderAll()
	if err != nil {
		http.BadWithDB(c, err)
		global.LmsLog.Error(err)
		return
	}
	http.Ok(c, li)
}

func (a questionApi) Question(c *gin.Context) {
	var in lms.SearchQuestion
	if err := c.ShouldBindQuery(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	li, total, err := repository.ExamDB.FindQuestionPage(in)
	if err != nil {
		global.LmsLog.Error(err)
		http.BadWithDB(c, err)
		return
	}
	http.OkPage(c, li, total)
}

func (a questionApi) ImportQuestion(c *gin.Context) {
	err := a.importQuestions(c)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a questionApi) CreateExamPaper(c *gin.Context) {
	var in lms.AddExamPaper
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	m := &tables.ExamPapers{
		Id:              id.GetSnowId(),
		Code:            in.Code,
		StartTime:       in.StartTime,
		EndTime:         in.EndTime,
		AllowRetest:     in.AllowRetest,
		RetestTime:      in.RetestTime,
		AllowSwitchPage: in.AllowSwitchPage,
		SwitchPageNum:   in.SwitchPageNum,
		ExamDuration:    in.ExamDuration,
		MustDuration:    in.MustDuration,
		Status:          enum.ExamPaperStatus.Working,
		AutoCreateInfo:  tables.AutoCreateInfo{},
	}
	err := global.DB.Save(&m).Error
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a questionApi) ExamPaperBindQuestion(c *gin.Context) {
	var in lms.ExamPaperBindQuestion
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	var (
		paper tables.ExamPapers
		qs    []tables.Question
		li    []tables.MapExamQuestions
		err   error
	)
	if global.DB.Where(&tables.ExamPapers{Id: in.ExamPaperId}).First(&paper).Error != nil {
		http.BadWithDB(c, err)
		return
	}
	if global.DB.Model(&tables.Question{}).Where("id in ?", in.QuestionId).Find(&qs).Error != nil {
		http.BadWithDB(c, err)
		return
	}
	self := http.GetCurrentUser(c)
	for _, v := range qs {
		li = append(li, tables.MapExamQuestions{
			Id:          id.GetSnowId(),
			ExamId:      paper.Id,
			QuestionId:  v.Id,
			Kind:        v.Kind,
			Title:       v.Title,
			SubTitle:    v.SubTitle,
			InputFun:    v.InputFun,
			Score:       v.Score,
			Options:     v.Options,
			Answer:      v.Answer,
			ScoringRule: v.ScoringRule,
			PartScore:   v.PartScore,
			HardLv:      v.HardLv,
			Label:       v.Label,
			FolderId:    v.FolderId,
			AutoCreateInfo: tables.AutoCreateInfo{
				Creator:   self.Nickname,
				CreatorId: self.UserID,
			},
		})
	}

	err = global.DB.Model(&tables.MapExamQuestions{}).CreateInBatches(li, len(li)).Error
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	paper.Status = enum.ExamPaperStatus.OK
	err = global.DB.Save(&paper).Error
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}

func (a questionApi) GetExamPaperPage(c *gin.Context) {
	var in lms.SearchExamPaperPage
	if err := c.ShouldBindQuery(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	li, total, err := repository.ExamDB.FindExamPaperPage(in)
	if err != nil {
		http.BadWithDB(c, err)
	}
	http.OkPage(c, li, total)
}

func (a questionApi) GetExamPaperQuestions(c *gin.Context) {
	in := struct {
		Id int64 `uri:"id"`
	}{}
	if err := c.ShouldBindUri(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	li, err := repository.ExamDB.FindQuestionListByPaperId(in.Id)
	if err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.Ok(c, li)
}

func (a questionApi) HandInPaper(c *gin.Context) {
	var in lms.HandInPaperDto
	if err := c.ShouldBindJSON(&in); err != nil {
		http.BadWithParamsError(c)
		return
	}
	var (
		paper tables.ExamPapers
		err   error
		li    []tables.ExamResult
	)
	if paper, err = repository.ExamDB.FindExamPaperById(in.ExamPaperId); err != nil {
		http.BadWithDB(c, err)
		return
	}
	self := http.GetCurrentUser(c)
	for _, v := range in.Answers {
		r := tables.ExamResult{
			Id:          id.GetSnowId(),
			UserId:      self.UserID,
			ExamPaperId: paper.Id,
			QuestionId:  v.QuestionId,
			UserAnswer:  v.UserAnswer,
			Scored:      0,
			ScoredMode:  0,
			AutoCreateInfo: tables.AutoCreateInfo{
				Creator:   self.Nickname,
				CreatorId: self.UserID,
				CreatedAt: time.Now().Unix(),
			},
		}
		li = append(li, r)
	}
	if err = repository.ExamDB.InsertExamResult(li); err != nil {
		http.BadWithDB(c, err)
		return
	}
	http.OK204(c)
}
